package com.example.project.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.project.mapper.LoginMapper;
import com.example.project.utils.*;
import com.example.project.vo.model.ChangePasswordVo;
import com.example.project.vo.model.UserDTO;
import com.example.project.exception.ServiceException;
import com.example.project.service.LoginService;
import com.example.project.vo.model.AuthUser;
import com.wf.captcha.ArithmeticCaptcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Resource
    private LoginMapper loginMapper;

    @Resource
    private JavaMailSender javaMailSender;

    @Override
    public void getCaptcha(String uuid, HttpServletResponse response) throws IOException {
        ArithmeticCaptcha captcha = new ArithmeticCaptcha();
        String code = captcha.text();
        log.info("uuid==>{},code==>{}", uuid, captcha.text());
        // RedisUtils.setString(Constants.Redis.CAPTCHA_KEY + uuid, code, 300);
        response.setContentType("image/jpeg");
        captcha.out(response.getOutputStream());
    }

    @Override
    public Map<String, Object> login(UserDTO userDTO) {

        List<AuthUser> authUserList = loginMapper.selectLogin(userDTO.getUsername());;
        AuthUser authUser = null;
        if (ObjectUtils.isNotEmpty(userDTO.getRole()) && CollectionUtils.isNotEmpty(authUserList)) {
            List<AuthUser> trueUsers = authUserList.stream().filter(innerUser -> {
                return userDTO.getRole().equals(innerUser.getRole());
            }).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(trueUsers)) {
                authUser = trueUsers.get(0);
            }
        } else if (CollectionUtils.isNotEmpty(authUserList)) {
            authUser = authUserList.get(0);
        }
        if (ObjectUtils.isEmpty(authUser)) {
            throw new ServiceException("无此账号！");
        }
        if (!authUser.getPassword().equals(SecureUtil.md5(userDTO.getPassword()))) {
            throw new ServiceException("密码错误！");
        }
        //登入成功后 生成 秘钥 和 当前用户 给前段
        Map<String, Object> map = createToken(authUser);
        return map;
    }


    @Override
    public void logout(HttpServletResponse response) {
        response.addHeader("token", null);
    }


    @Override
    public void changePassword(ChangePasswordVo changePasswordVo) {

        if (!changePasswordVo.getNewPasswordOne().equals(changePasswordVo.getNewPasswordTwo()))
            throw new ServiceException("新密码不一致！");
        switch (changePasswordVo.getChangeType()) {
            case EMAIL_CODE:

                if (!changePasswordVo.getEmailCode().equals(EmailUtils.cacheMap.get(changePasswordVo.getEmail())))
                    throw new ServiceException("验证码错误！");
                loginMapper.changePasswordByEmail(changePasswordVo.getNewPasswordTwo(), changePasswordVo.getEmail());
                EmailUtils.cacheMap.remove(changePasswordVo.getEmail());
                break;
            case OLD_PASSWORD:
                Long id = SecurityUtils.getUser().getId();
                String oldPassword = loginMapper.getOldPassword(id);
                if (!oldPassword.equals(changePasswordVo.getOrdPassword()))
                    throw new ServiceException("原密码错误！");
                loginMapper.changePasswordById(changePasswordVo.getNewPasswordTwo(), id);
        }

    }

    @Override
    public void sendEmailCode(String email) {
        if (StringUtils.isEmpty(email)) throw new ServiceException("email 未输入！");
        String code = getCode();
        EmailUtils.sendSimpleMail(email, code, javaMailSender);
        log.info("email=>{},code=>{}", email, code);
         EmailUtils.cacheMap.put(email,code);
    }


    private String getCode() {
        ArithmeticCaptcha captcha = new ArithmeticCaptcha();
        String code = captcha.text();
        return code;
    }


    private Map<String, Object> createToken(AuthUser authUser) {
        // 用户登录成功后 基本信息id,name生成 token
        String token = JwtUtils.createToken(authUser);
        // 查询用户的 roleId，组装成 list
        Set<Integer> roleIdSet = new HashSet<>();
        roleIdSet.add(authUser.getRole().getRoleId());
        HashMap<String, Object> map = new HashMap<>();
        map.put("user", authUser);
        map.put("token", token);
        return map;
    }
}
